#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name：    json_util.py
   Author :       zyq
   CreateDate：   2024/7/19 21:43
   Remark :  json数据解析
-------------------------------------------------
"""

import json

import allure
import jsonpath
import jsonschema

from guitesting.common.util.logs import Log


class JsonUtil:
    @staticmethod
    def load_json(data):
        """
        从给定的字符串中加载并解析JSON数据。

        Args:
            data (str): 待解析的JSON格式的字符串。

        Returns:
            dict: 解析后的JSON数据，以字典形式返回。

        Raises:
            json.JSONDecodeError: 如果给定的字符串无法被解析为有效的JSON数据。

        """
        return json.loads(data)

    @staticmethod
    def dumps_josn(data):
        """
        将Python对象序列化为JSON格式的字符串。

        Args:
            data (Any): 需要被序列化的Python对象，支持Python内置类型、自定义类型等。

        Returns:
            str: 序列化后的JSON格式字符串。

        """
        return json.dumps(data)

    @staticmethod
    def jsonToOneValue(jsonObj: str, rule: str):
        """
        从给定的JSON字符串中根据规则提取一个值。

        Args:
            jsonObj (str): 要解析的JSON字符串。
            rule (str): 用于从JSON中提取数据的规则（JSONPath表达式）。

        Returns:
            Union[Any, List[Any]]: 从JSON中提取出的一个值或值的列表（取决于JSONPath表达式的结果）。

        Raises:
            Exception: 如果JSON解析失败或未获取到数据，则抛出异常。

        """
        # 使用jsonpath库解析jsonObj并根据rule规则提取数据
        __data = jsonpath.jsonpath(jsonObj, rule)

        # 如果解析结果为False，则抛出异常
        if __data is False:
            raise Exception(f"json解析失败没有获取到数据:\njson:{jsonObj}\n解析规则:{rule}")

        # 返回解析结果
        return __data

    @staticmethod
    def assert_jsonschema(response: dict, schema):
        """
        对实际响应结果进行JSON Schema断言

        Args:
            response (dict): 实际响应结果的字典表示
            schema: JSON Schema，用于验证响应结果的正确性

        Returns:
            无返回值，但会抛出异常或记录日志

        Raises:
            jsonschema.exceptions.ValidationError: 当响应结果不符合JSON Schema时抛出
            jsonschema.exceptions.SchemaError: 当JSON Schema本身存在错误时抛出

        """
        try:
            # 开始进行jsonschema校验
            Log.info("jsonschema校验开始")
            # 使用jsonschema库的validate函数进行校验，验证响应结果是否符合JSON Schema
            jsonschema.validate(instance=response, schema=schema, format_checker=jsonschema.draft7_format_checker)
            # 如果校验通过，则记录日志
            Log.info("jsonschema校验通过")
            # 在allure报告中记录步骤，表示jsonschema校验通过
            allure.step(f"jsonschema校验通过")
        except (jsonschema.exceptions.ValidationError, jsonschema.exceptions.SchemaError) as e:
            # 如果校验失败，则记录错误日志
            Log.error(f"jsonschema校验失败，报错信息为： {e}")
            # 在allure报告中记录步骤，表示jsonschema校验失败，并显示错误信息
            allure.step(f"jsonschema校验失败,报错信息为： {e}")
            # 抛出异常
            raise e


if __name__ == '__main__':
    json1 = """{
    "invoiceItems":[
        {
            "insurance":"DING_E",
            "invoiceCorp":"1517:171",
            "serviceFee":"ZHI_ZHI_ZENG_PU",
            "flight":"ZHI_ZHI_ZENG_PU",
            "intlFlight":"ZHI_ZHI_ZENG_PU",
            "intlHotel":"ZHI_ZHI_ZENG_PU",
            "general":"ZHI_ZHI_ZENG_PU",
            "trainTicketService":"ZHI_ZHI_ZENG_PU",
            "car":"NON_INVOICE",
            "hotel":"ZHI_ZHI_ZENG_PU",
            "receiptCorps":"172,397,1619",
            "flightRefundFee":"DIAN_ZHI_ZENG_PU",
            "flightCheap":"ZHI_ZHI_ZENG_PU",
            "train":"NON_INVOICE"
        }
    ],
    "invoiceCategory":"SINGLE_CORP"
}"""
    print(JsonUtil.jsonToOneValue(JsonUtil.load_json(json1), rule='$.invoiceItems[0].receiptCorps'))
